<template>
  <div>
    <el-card class="box-card" shadow="hover">
      <div>
        <el-form ref="searchForm" :inline="true" :model="searchForm" :rules="rules" size="mini">
          <el-form-item prop="date">
            <el-date-picker v-model="searchForm.date" placeholder="选择日期" style="width: 150px" type="date"
                            value-format="yyyy-MM-dd"/>
          </el-form-item>
          <el-form-item prop="time">
            <el-time-picker v-model="searchForm.time" end-placeholder="结束时间" is-range placeholder="选择时间范围"
                            range-separator="至" start-placeholder="开始时间" style="width: 200px" value-format="HH:mm:ss"/>
          </el-form-item>
          <el-form-item prop="instance">
            <el-cascader v-model="searchForm.instance" :options="instanceOptions" :props="{ expandTrigger: 'hover' }"
                         style="width: 260px"/>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSearch">查询</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div id="jvmChart" class="chartDiv"/>
      <div id="threadsChart" class="chartDiv"/>
      <div id="cpuChart" class="chartDiv"/>
    </el-card>
  </div>
</template>
<script>
import {appInstanceListApi, deployGroupListApi} from "@/api/manage";
import * as echarts from "echarts";
import {queryDataListApi} from "@/api/monitor";

export default {
  props: {
    appName: [String],
  },
  data() {
    return {
      charts: {},
      instanceOptions: [],
      searchForm: {},
      jvmOption: {},
      baseOption: {
        title: {left: 'left',},
        legend: {left: 'right'},
        grid: {top: 60, left: 60, right: 30, bottom: 30},
        xAxis: {type: 'time'},
        yAxis: {
          type: 'value',
          splitNumber: 4, scale: true
        },
        tooltip: {
          trigger: 'axis'
        },
      },
      rules: {
        date: [
          {
            required: true,
            message: "请输入日期",
            trigger: ["blur", "change"],
          },
        ],
      },
    };
  },
  watch: {
    appName() {
      this.loadInstanceOptions();
    }
  },
  methods: {
    dateFormat(fmt, date) {
      let ret;
      const opt = {
        "Y+": date.getFullYear().toString(), // 年
        "m+": (date.getMonth() + 1).toString(), // 月
        "d+": date.getDate().toString(), // 日
        "H+": date.getHours().toString(), // 时
        "M+": date.getMinutes().toString(), // 分
        "S+": date.getSeconds().toString(), // 秒
        // 有其他格式化字符需求可以继续添加，必须转化成字符串
      };
      for (let k in opt) {
        ret = new RegExp("(" + k + ")").exec(fmt);
        if (ret) {
          fmt = fmt.replace(
              ret[1],
              ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0")
          );
        }
      }
      return fmt;
    },
    onClickIns(ins) {
      this.logLines = ins.logLines;
    },
    onSearch() {
      this.$refs["searchForm"].validate((valid) => {
        if (valid) {
          this.doSearch();
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    doSearch() {
      this.loadChartData("jvmChart");
      this.loadChartData("threadsChart");
      this.loadChartData("cpuChart");
    },
    initSearchQuery() {
      this.searchForm = {instance: []};
      this.instanceOptions = [];
      this.$set(this.searchForm, "date", this.dateFormat("YYYY-mm-dd", new Date()));
      this.$set(this.searchForm, "time", [
        this.dateFormat("HH:MM:00", new Date(new Date().getTime() - 1000 * 60 * 60)),
        this.dateFormat("HH:MM:00", new Date(new Date().getTime() + 1000 * 60 * 1)),
      ]);
    },
    async loadChartData(divId) {
      let begin = this.searchForm.date + ' ' + this.searchForm.time[0];
      let end = this.searchForm.date + ' ' + this.searchForm.time[1];
      let keys = [];
      for (let k in this.charts[divId].keyTypes) {
        keys.push(k);
      }
      let dataList = await queryDataListApi({
        instanceIds: this.searchForm.instance[1],
        keyTypes: keys.join(","),
        begin: begin,
        end: end,
      });
      let keyMap = {};
      let seriesMap = {};
      let legend = [];
      let selected = {};
      for (let i in dataList) {
        let data = dataList[i];
        if (!seriesMap[data.keyType.code]) {
          seriesMap[data.keyType.code] = [];
          keyMap[data.keyType.code] = data.keyType;
          legend.push(data.keyType.name);
          selected[data.keyType.name] = this.charts[divId].keyTypes[data.keyType.code];
        }
        let v = this.formatValue(data.keyType.code, data.value);
        seriesMap[data.keyType.code].push([data.time, v]);
      }
      let series = [];
      for (let key in seriesMap) {
        series.push({
          name: keyMap[key].name,
          type: 'line',
          smooth: true,
          showSymbol: false,
          data: seriesMap[key]
        });
      }

      this.charts[divId].option.series = series;
      this.charts[divId].option.legend.data = legend;
      this.charts[divId].option.legend.selected = selected;
      this.charts[divId].option.xAxis.min = begin;
      this.charts[divId].option.xAxis.max = end;
      this.charts[divId].chartInstance.setOption(this.charts[divId].option, true);
    },
    formatValue(code, value) {
      switch (code) {
        case 'JVM_MEMORY_MAX':
        case 'JVM_MEMORY_USED':
        case 'JVM_MEMORY_COMMITTED':
          return Math.round(value / 1024 / 1024);
        case 'SYSTEM_LOAD_AVERAGE':
        case 'SYSTEM_CPU_USAGE':
        case 'PROCESS_CPU_USAGE':
          return Math.round(value * 10000) / 100;
      }
      return value;
    },
    async loadInstanceOptions() {
      this.initSearchQuery();
      if (!this.appName) return;
      let deployGroups = await deployGroupListApi(this.appName);
      for (let i in deployGroups) {
        let g = deployGroups[i];
        let data = {value: g.name, label: g.showName, children: []};
        let instanceList = await appInstanceListApi(g.appName, g.name);
        if (instanceList) {
          for (let j in instanceList) {
            data.children.push({
              value: instanceList[j].id,
              label: instanceList[j].name,
            });
          }
        }
        this.instanceOptions.push(data);
      }

      if (this.searchForm.instance == null && this.instanceOptions.length > 0 && this.instanceOptions[0].children.length > 0) {

        this.$set(this.searchForm, "instance", [this.instanceOptions[0].value, this.instanceOptions[0].children[0].value]);
        this.onSearch();
      }
    },
    initChart(divId, title, yAxisName, keyTypes) {
      let option = JSON.parse(JSON.stringify(this.baseOption));
      option.title.text = title;
      option.yAxis.name = yAxisName;
      this.charts[divId] = {
        chartInstance: echarts.init(document.getElementById(divId), 'dark'),
        option: option,
        keyTypes: keyTypes,
      }
      this.charts[divId].chartInstance.setOption(this.charts[divId].option);
    }
  },
  mounted() {
    this.initChart("jvmChart", 'JVM', '单位:M', {
      JVM_MEMORY_MAX: false,
      JVM_MEMORY_USED: true,
      JVM_MEMORY_COMMITTED: true
    });
    this.initChart("threadsChart", '线程数', '单位:个', {
      JVM_THREADS_PEAK: true,
      JVM_THREADS_LIVE: true,
      JVM_THREADS_DAEMON: true
    });
    this.initChart("cpuChart", 'CPU', '单位:%', {
      SYSTEM_LOAD_AVERAGE: false,
      SYSTEM_CPU_USAGE: false,
      PROCESS_CPU_USAGE: true
    });
    this.loadInstanceOptions();
  },
};
</script>
<style scoped>
.chartDiv {
  width: 100%;
  height: 300px;
  margin-bottom: 10px;
}
</style>